package zorm

import (
	"fmt"
	"strings"
	"gitee.com/zouyang8210/zjson"
)

type MySql struct {
	dbCli Db
}

func (c *MySql) Initialize(uid, pw, addr, dbName, port string) {
	c.dbCli, _ = New(uid, pw, addr, dbName, port)
	c.SetWriteDebug(true)
	c.SetReadDebug(true)
}

func (c *MySql) SetWriteDebug(v bool) {
	c.dbCli.Debug = v
}

func (c *MySql) SetReadDebug(v bool) {
	c.dbCli.recycle = v
}

func (c *MySql) Begin() (transaction Tx, err error) {
	return c.dbCli.Begin()
}

func (c *MySql) NewCondition() (cond Conditions) {
	return c.dbCli.NewCondition()
}

func (c *MySql) Insert(tbName string, obj interface{}, tx *Tx, flag bool, fields ...string) (result int64, err error) {
	result, err = c.dbCli.Insert(tbName, obj, tx, flag, fields...)
	return
}

func (c *MySql) Update(tbName string, obj interface{}, cond Conditions, tx *Tx, flag bool, fields ...string) (result int64, err error) {
	result, err = c.dbCli.Update(tbName, obj, cond, tx, flag, fields...)
	return
}

func (c *MySql) UpdateSingle(tbName string, field string, value interface{}, cond Conditions, tx *Tx) (result int64, err error) {
	result, err = c.dbCli.UpdateSingle(tbName, field, value, cond, tx)
	return
}

func (c *MySql) QueryObject(tbName string, cond Conditions, obj interface{}, tx *Tx, fields ...string) (err error) {
	err = c.dbCli.QueryObject(tbName, cond, obj, tx, fields...)
	return
}

func (c *MySql) Query(sql string, obj interface{}, tx *Tx) (err error) {
	var record RecordSet
	record, err = c.dbCli.Query(sql, tx)
	if len(record.Data) > 0 && record.Count > 0 {
		e := zjson.ObjToObj(&obj, record.Data)
		if e != nil {
			fmt.Println(e)
		}
	}
	return
}

func (c *MySql) Exec(sql string, tx *Tx) (count int64, err error) {
	count, err = c.dbCli.Execute(sql, tx)
	return
}

func (c *MySql) QuerySingle(tbName string, cond Conditions, obj interface{}, tx *Tx, fields ...string) (err error) {
	err = c.dbCli.QuerySingle(tbName, cond, obj, tx, fields...)
	return
}

func (c *MySql) Delete(tbName string, cond Conditions, tx *Tx) (count int64, err error) {
	count, err = c.dbCli.Delete(tbName, cond, tx)
	return
}

// GetRowsCount 获取数据行数
func (c *MySql) GetRowsCount(tbName string, cond Conditions) (count int64, err error) {
	cond.ClearOther()
	stat := struct {
		Count int64 `json:"count"`
	}{}
	if err = c.dbCli.QuerySingle(tbName, cond, &stat, nil, "COUNT(*) as count"); err == nil {
		count = stat.Count
	}
	return
}

// GetNow 获取数据当前时间
func (c *MySql) GetNow() (now string, err error) {
	var result RecordSet
	if result, err = c.dbCli.Query("select now() as now", nil); err == nil {
		now = strings.Replace(result.Data[0]["now"].(string), "T", " ", 1)
		now = strings.Replace(now, "Z", " ", 1)
	}
	return
}

func (c *MySql) TableIsExist(tableName string) bool {
	o := struct {
		TableSchema string `json:"TABLE_SCHEMA"`
		TableName   string `json:"TABLE_NAME"`
	}{}
	strSql := fmt.Sprintf("select * from information_schema.`TABLES` where table_name='%s' limit 1", tableName)

	if e := c.Query(strSql, &o, nil); e != nil {
		return false
	}
	if o.TableName == "" {
		return false
	}

	return true
}

// T 表名加上字段组合
func (c *MySql) T(tName string, fName string, as ...string) string {
	str := tName + "." + fName
	if len(as) > 0 {
		str += " as" + as[0]
	}
	return str
}

// L 模糊匹配组合
func (c *MySql) L(v string) string {
	return "%" + v + "%"
}

// F 字段计算组合
func (c *MySql) F(f string, v int) string {
	return fmt.Sprintf("%s+%d", f, v)
}

func (c *MySql) CreateStruct(tableName, filePath string) (e error) {
	return c.dbCli.CreateTableStruct(tableName, filePath)
}
